package org.cyhz.standardize.service;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.cyhz.domain.SbVO;
import org.cyhz.domain.SsNsVO;
import org.cyhz.domain.SsVO;
import org.cyhz.util.Log;
import org.springframework.stereotype.Service;

import ch.lambdaj.Lambda;

@Service("sSeriesSearchService")
public class SSeriesSearchServiceImp implements SSeriesSearchService {

	private Comparator<String> comparator = new Comparator<String>() {
		@Override
		public int compare(String o1, String o2) {
			return o2.length() - o1.length();
		}
	};

	private List<String> getAllNs() {
		return new ArrayList<>(StandardizeResources.nsssMapping.keySet());
	}

	@Override
	public List<SsVO> getSseriesList(String tc, List<String> nss) {
		List<SsVO> ssvos = new ArrayList<>();
		if (null == nss || nss.isEmpty()) {
			nss = getAllNs();
		}

		// Entry<SsNsVO.toString,SsNsVO>
		Map<String, SsNsVO> ns_ssnsMapping = new HashMap<>();
		for (String ns : nss) {
			if (StandardizeResources.ns_ssnsMapping.containsKey(ns)) {
				List<SsNsVO> ssnsvos = StandardizeResources.ns_ssnsMapping
						.get(ns);
				for (SsNsVO ssNsVO : ssnsvos) {
					ns_ssnsMapping.put(ssNsVO.toString(), ssNsVO);
				}
			}
		}
		// 非标准车系只对应一个标准车系
		// Entry<SsNsVO.n,SsNsVO>
		Map<String, SsNsVO> suit_nsname_ssnsMapping = new HashMap<>();
		for (SsNsVO ssnsvo : ns_ssnsMapping.values()) {
			suit_nsname_ssnsMapping.put(ssnsvo.getN(), ssnsvo);
		}
		// finish get suit nss

		Map<String, SsNsVO> containsNsName_SsNsMapping = new HashMap<>();
		List<String> nsNames = new ArrayList<>(suit_nsname_ssnsMapping.keySet());
		// 按长度降序
		// List<String> lengthSortedNsName = Lambda.sort(nsNames,
		// Lambda.on(String.class).length());

		List<String> lengthSortedNsName = new ArrayList<>(nsNames);
		Collections.sort(lengthSortedNsName, comparator);

		// 保存已经被包含的非标准车系名，用于过滤后续的被包含的非标准车系名做验证
		List<String> containsNsNames = new ArrayList<>();

		for (String nsname : lengthSortedNsName) {
			if (tc.contains(nsname)) {
				String name = whichContains(containsNsNames, nsname);
				if (StringUtils.isBlank(name)) {
					containsNsName_SsNsMapping.put(nsname,
							suit_nsname_ssnsMapping.get(nsname));
					containsNsNames.add(nsname);
					Log.info(tc + " contains ns " + nsname);
				} else {
					Log.info(name + " contains ns " + nsname + ",ignore "
							+ nsname);
				}
			}
		}

		List<SsNsVO> ssnss = new ArrayList<>(
				containsNsName_SsNsMapping.values());

		Map<String, SsVO> ssname_ssvoMap = new HashMap<>();

		for (SsNsVO ssNsVO : ssnss) {
			ssname_ssvoMap.put(ssNsVO.getS(),
					StandardizeResources.ssName_ssvoMapping.get(ssNsVO.getS()));
		}

		ssvos.addAll(ssname_ssvoMap.values());
		return ssvos;
	}

	@Override
	public List<SsVO> getSseriesListFromSN(String sb, String ns) {

		if (StringUtils.isBlank(sb)) {
			return null;
		} else {
			if (StringUtils.isBlank(ns)) {
				Log.debug("get ss by ns from ssns,null");
				return null;
			} else {
				// sb is not null
				List<SsVO> ssvo1 = this.getSsListBySb(sb);
				if (null == ssvo1 || ssvo1.isEmpty()) {
					Log.debug("get ss by sb from sbss,null");
					return null;
				} else {
					// ss from sb is not null
					List<SsVO> ssvo2 = this.getSsListByNs(ns);
					if (null == ssvo2 || ssvo2.isEmpty()) {
						Log.debug("get ssvo by ns in sb is empty");
						return null;
					} else {
						Log.debug("get ss by sb from sbss,"
								+ Lambda.join(ssvo1));
						Log.debug("get ss by ns from ssns,"
								+ Lambda.join(ssvo2));
						List<SsVO> ssvos = getSsVOIntersection(ssvo1, ssvo2);
						return ssvos;
					}
				}
			}
		}
	}

	private List<SsVO> getSsListByNs(String ns) {

		if (StringUtils.isBlank(ns)) {
			return null;
		}

		if (StandardizeResources.nsssMapping.containsKey(ns)) {
			return StandardizeResources.nsssMapping.get(ns);
		} else {
			return null;
		}
	}

	private List<SsVO> getSsListBySb(String sb) {

		if (StringUtils.isBlank(sb)) {
			return null;
		}

		if (StandardizeResources.sbName_sbvoMapping.containsKey(sb)) {
			SbVO sbvo = StandardizeResources.sbName_sbvoMapping.get(sb);
			if (StandardizeResources.sbssMapping.containsKey(sbvo)) {
				return StandardizeResources.sbssMapping.get(sbvo);
			} else {
				return null;
			}
		} else {
			return null;
		}

	}

	private Map<String, SsVO> getSsMap(List<SsVO> sss) {
		Map<String, SsVO> nameSsvoMapping = new HashMap<>();
		for (Iterator<SsVO> i = sss.iterator(); i.hasNext();) {
			SsVO ssVO = (SsVO) i.next();
			nameSsvoMapping.put(ssVO.getSeries(), ssVO);
		}
		return nameSsvoMapping;
	}

	private List<SsVO> getSsVOIntersection(List<SsVO> ssvo1, List<SsVO> ssvo2) {
		List<SsVO> ssvos = new ArrayList<>();
		Map<String, SsVO> m1 = getSsMap(ssvo1);
		Map<String, SsVO> m2 = getSsMap(ssvo2);
		for (String sname : m1.keySet()) {
			if (m2.containsKey(sname)) {
				ssvos.add(m2.get(sname));
			}
		}
		return ssvos;
	}

	private String whichContains(List<String> lengther, String ns) {
		for (String s : lengther) {
			if (s.contains(ns)) {
				return s;
			}
		}
		return null;
	}

	@Override
	public List<SsVO> getSseriesListFromByNs(String ns) {
		return getSsListByNs(ns);
	}

	@Override
	public List<SsVO> getSseriesListFromBySb(String sb) {
		return this.getSsListBySb(sb);
	}

}
